package com.flute.datareceiver.data.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import com.flute.datareceiver.data.constants.ServiceConstants;
import com.flute.framework.FluteMonitor;
import com.flute.framework.data.impl.ServiceContext;
import com.flute.framework.monitor.EventLogger;
import com.flute.framework.monitor.MonitedValue;
import com.flute.tools.util.ExceptionUtil;
import com.flute.tools.util.StringUtil;

public class DataReceiveService extends HttpServlet {
	private static final long serialVersionUID = -4190146250531884436L;

	public DataReceiveService() {
		super();
	}

	/**
	 * The doGet method of the servlet. <br>
	 * 
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request
	 *            the request send by the client to the server
	 * @param response
	 *            the response send by the server to the client
	 * @throws ServletException
	 *             if an error occurred
	 * @throws IOException
	 *             if an error occurred
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doPost(request, response);
	}

	/**
	 * The doPost method of the servlet. <br>
	 * 
	 * This method is called when a form has its tag value method equals to
	 * post.
	 * 
	 * @param request
	 *            the request send by the client to the server
	 * @param response
	 *            the response send by the server to the client
	 * @throws ServletException
	 *             if an error occurred
	 * @throws IOException
	 *             if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		EventLogger.startNewEvent(FluteMonitor.getRecieverKey());
		info("数据接收服务启动......");
		Properties properties = loadProperties();
		/*
		 * String url = request.getRemoteAddr(); if (isValidURL(url,
		 * properties)) { String fileName = System.currentTimeMillis() +
		 * ServiceConstants.XML_FILE; try {
		 * request.setCharacterEncoding(ServiceConstants.CHAR_SET_UTF8);
		 * InputStream inputStream = request.getInputStream();
		 * 
		 * String type = request.getParameter(ServiceConstants.TYPE);
		 * info("数据接收类型" + type); if (!isNullOrEmpty(type)) { String folderName
		 * = getFolderPath(type, properties); info("数据接收类型的文件路径" + folderName);
		 * 
		 * saveFile(folderName, fileName, inputStream); } else {
		 * warn("不能找到有效的类型参数，请检查后重试"); } } catch (Exception e) {
		 * error("移动文件时出错，程序退出.\n" + ExceptionUtil.getExceptionContent(e));
		 * response.setStatus(HttpServletResponse.SC_BAD_REQUEST); } }
		 */
		String fileName = System.currentTimeMillis()
				+ ServiceConstants.XML_FILE;
		try {
			request.setCharacterEncoding(ServiceConstants.CHAR_SET_UTF8);
			InputStream inputStream = request.getInputStream();

			String type = request.getParameter(ServiceConstants.TYPE);
			info("数据接收类型" + type);
			if (!isNullOrEmpty(type)) {
				String storeType = properties.getProperty(type, type);
				String[] folders = storeType.split(",");
				List<String> pathList = new ArrayList<String>();
				for (String folder : folders) {
					String folderName = getFolderPath(folder, properties);
					pathList.add(folderName);
					info("数据接收类型的文件路径" + folderName);
				}

				saveFile(pathList, fileName, inputStream);
			} else {
				warn("不能找到有效的类型参数，请检查后重试");
			}
		} catch (Exception e) {
			error("移动文件时出错，程序退出.\n" + ExceptionUtil.getExceptionContent(e));
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
		}
		info("数据接收服务结束......");
	}

	@SuppressWarnings("unused")
	private boolean isValidURL(String url, Properties properties) {
		List<String> urls = getUrls(properties);
		return urls.contains(url);
	}

	private List<String> getUrls(Properties properties) {
		List<String> urlList = new ArrayList<String>();
		if (properties != null) {
			String urlString = properties.getProperty(ServiceConstants.URLS);
			if (!StringUtil.isNullOrEmpty(urlString)) {
				String[] urls = urlString.split(",");
				urlList = Arrays.asList(urls);
			}
		}
		return urlList;
	}

	private Properties loadProperties() {
		Properties p = new Properties();
		InputStream in = this.getClass().getClassLoader()
				.getResourceAsStream(ServiceConstants.PARA_PROPERTIEST_NAME);
		try {
			info("加载" + ServiceConstants.PARA_PROPERTIEST_NAME + "文件");
			p.load(in);
			info("加载" + ServiceConstants.PARA_PROPERTIEST_NAME + "文件成功");
		} catch (IOException e) {
			error("加载" + ServiceConstants.PARA_PROPERTIEST_NAME + "文件失败"
					+ ExceptionUtil.getExceptionContent(e));
		}

		return p;
	}

	private void warn(String message) {
		EventLogger.warn(new MonitedValue(message),
				EventLogger.getCurrentEventId(FluteMonitor.getRecieverKey()));
	}

	private void error(String message) {
		EventLogger.error(new MonitedValue(message),
				EventLogger.getCurrentEventId(FluteMonitor.getRecieverKey()));
	}

	private void info(String message) {
		EventLogger.info(new MonitedValue(message),
				EventLogger.getCurrentEventId(FluteMonitor.getRecieverKey()));
	}

	private String getFolderPath(String type, Properties p) {
		String testPath = p.getProperty(ServiceConstants.DATA_DIRECTORY_TEST);
		String path = p.getProperty(ServiceConstants.DATA_DIRECTORY);
		String realPath = testPath.equals(ServiceConstants.TEST) ? ServiceContext
				.getRootDir() + File.separator + ServiceConstants.DATA_FILENAME
				: path;
		return realPath + File.separator + type + File.separator;
	}

	private boolean isNullOrEmpty(String type) {
		return type == null
				|| type.trim().equals(ServiceConstants.EMPTY_STRING);
	}

	public void saveFile(List<String> paths, String fileName, InputStream is)
			throws IOException {
		String tempFileName = System.currentTimeMillis()
				+ ServiceConstants.TMP_FILE;

		mkdirIfNotExists(paths);

		String content = getContent(is);

		for (String path : paths) {
			FileOutputStream out = new FileOutputStream(path + tempFileName);
			OutputStreamWriter fw = new OutputStreamWriter(out,
					ServiceConstants.CHAR_SET_UTF8);

			fw.write(content);
			fw.flush();
			fw.close();
			info("开始移动文件从" + path + tempFileName + "移动到" + path + fileName);
			// copy temp file
			FileUtils.moveFile(new File(path + tempFileName), new File(path
					+ fileName));
		}
		info("移动成功");
	}

	private void mkdirIfNotExists(List<String> paths) throws IOException {
		for (String path : paths) {
			File folder = new File(path);
			if (!folder.exists()) {
				FileUtils.forceMkdir(folder);
			}
		}
	}

	private String getContent(InputStream is) throws IOException {
		String content = IOUtils.toString(is, ServiceConstants.CHAR_SET_UTF8);
		is.close();
		return content;
	}

}
